package com.momo.configuration.mp;

import me.chanjar.weixin.common.bean.WxAccessToken;
import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
import me.chanjar.weixin.mp.enums.TicketType;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;

/**
 * Created by Kagome on 2019/5/16.
 */
public class WxMpSpringRedisConfigStorage extends WxMpInMemoryConfigStorage {
    private final static String ACCESS_TOKEN_KEY = "wechat_access_token_";

    private final static String JSAPI_TICKET_KEY = "wechat_jsapi_ticket_";

    private final static String CARDAPI_TICKET_KEY = "wechat_cardapi_ticket_";

    private final static String SDK_TICKET_KEY = "wechat_sdk_ticket_";

    private final RedisTemplate<String, String> redisTemplateString;


    private String accessTokenKey;

    private String jsapiTicketKey;

    private String cardapiTicketKey;

    private String sdkTicketKey;

    public WxMpSpringRedisConfigStorage(RedisTemplate<String, String> redisTemplateString) {
        this.redisTemplateString = redisTemplateString;
    }

    @Override
    public void setAppId(String appId) {
        super.setAppId(appId);
//        定义redis中存储的名称
        this.accessTokenKey = ACCESS_TOKEN_KEY.concat(appId);
        this.jsapiTicketKey = JSAPI_TICKET_KEY.concat(appId);
        this.cardapiTicketKey = CARDAPI_TICKET_KEY.concat(appId);
        this.sdkTicketKey = SDK_TICKET_KEY.concat(appId);
    }

    @Override
    public String getAccessToken() {
        String accessTokenKey = redisTemplateString.opsForValue().get(this.accessTokenKey);
        return accessTokenKey;
    }

    @Override
    public boolean isAccessTokenExpired() {
        return redisTemplateString.getExpire(this.accessTokenKey) < 2;
    }

    @Override
    public synchronized void updateAccessToken(WxAccessToken accessToken) {
        updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn());
    }

    @Override
    public synchronized void updateAccessToken(String accessToken, int expiresInSeconds) {
        redisTemplateString.opsForValue().set(this.accessTokenKey, accessToken, expiresInSeconds - 200, TimeUnit.SECONDS);
    }

    @Override
    public void expireAccessToken() {
        redisTemplateString.expire(this.accessTokenKey, 0, TimeUnit.SECONDS);
    }

    @Override
    public String getTicket(TicketType type) {
        switch (type) {
            case SDK:
                return this.sdkTicketKey;
            case JSAPI:
                return this.jsapiTicketKey;
            case WX_CARD:
                return this.cardapiTicketKey;
            default:
                return null;
        }
    }

    @Override
    public boolean isTicketExpired(TicketType type) {
        switch (type) {
            case SDK:
                return redisTemplateString.getExpire(this.sdkTicketKey, TimeUnit.SECONDS) < 2;
            case JSAPI:
                return redisTemplateString.getExpire(this.jsapiTicketKey, TimeUnit.SECONDS) < 2;
            case WX_CARD:
                return redisTemplateString.getExpire(this.cardapiTicketKey, TimeUnit.SECONDS) < 2;
            default:
                return false;
        }
    }
    @Override
    public synchronized void updateTicket(TicketType type, String ticket, int expiresInSeconds) {
        switch (type) {
            case JSAPI:
                // 预留200秒的时间
                redisTemplateString.opsForValue().set(this.jsapiTicketKey,ticket,expiresInSeconds - 200,TimeUnit.SECONDS);
                break;
            case WX_CARD:
                // 预留200秒的时间
                redisTemplateString.opsForValue().set(this.cardapiTicketKey,ticket,expiresInSeconds - 200,TimeUnit.SECONDS);
                break;
            case SDK:
                // 预留200秒的时间
                redisTemplateString.opsForValue().set(this.sdkTicketKey,ticket,expiresInSeconds - 200,TimeUnit.SECONDS);
                break;
            default:
        }
    }
    @Override
    public void expireTicket(TicketType type) {
        switch (type) {
            case JSAPI:
                redisTemplateString.expire(this.jsapiTicketKey,0,TimeUnit.SECONDS);
                break;
            case WX_CARD:
                redisTemplateString.expire(this.cardapiTicketKey,0,TimeUnit.SECONDS);
                break;
            case SDK:
                redisTemplateString.expire(this.sdkTicketKey,0,TimeUnit.SECONDS);
                break;
            default:
        }
    }
    @Override
    public String getJsapiTicket() {
        return redisTemplateString.opsForValue().get(this.jsapiTicketKey);
    }

    @Override
    public String getCardApiTicket() {
        return redisTemplateString.opsForValue().get(this.cardapiTicketKey);
    }


}
